﻿using Kaskelot.SP.Core;
using Kaskelot.SP.Model.Client;
using Kaskelot.SP.Model.Client.Forms;
using Kaskelot.SP.Services.Client.Mapping;
using Microsoft.SharePoint;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace Kaskelot.SP.Services.Client
{
	[ServiceContract(Namespace = "http://Kaskelot.SP.Services")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class ClientKursService
	{
		#region Kurser
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientKurs>> GetKurser()
		{
			ClientServiceResult<IEnumerable<ClientKurs>> csr = new ClientServiceResult<IEnumerable<ClientKurs>>();

			try
			{
				using (KursService svc = new KursService())
				{
					csr.Data = svc.GetKurser().Select(k => k.ToClientContract()).OrderBy(k => k.Beskrivning);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateKurs(KursForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					Kurs k = svc.GetKurs(new Guid(form.Id));
					k.Andrad = DateTime.Now;
					k.AndradAv = SPContext.Current.Web.CurrentUser.Name;

					k.UpdateContract(form);
					svc.UpdateKurs(k);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateKurs(KursForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					Kurs k = new Kurs()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id,
						Id = Guid.NewGuid()
					};
					k.UpdateContract(form);
					svc.CreateKurs(k);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteKurs(KursForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (form.Id.IsGuid())
					{
						svc.DeleteKurs(new Guid(form.Id));
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.HasError = true;
				csr.ErrorMessage = "Kursen gick inte att ta bort. Kontrollera att det inte finns några kurstillfällen kopplade till kursen.";
			}

			return csr;
		}

		#endregion

		#region Kurstillfälle
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> SkickaSMS(string ktId, string mobtelnrList, string text)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			using (KursService svc = new KursService())
			{
				IList<string> mottagare = new List<string>();

				if (ktId.IsGuid())
				{
					var pkt = svc.GetPersonKursTillfallenByKursTillfalleId(new Guid(ktId));
					mottagare = pkt.Where(x => x.PersonMobTelNr.IsNonEmpty()).Select(x => x.PersonMobTelNr).ToArray();
				}
				else if (mobtelnrList != null)
				{
					mottagare = mobtelnrList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
				}

				NotifieringsResultat res = svc.SkickaSMS(mottagare, text);
				if (res.Fel)
				{
					csr.HasError = true;
					if(res.FelKod.IsNonEmpty())
						csr.ErrorMessage = "Ett fel inträffade. Felkod " + res.FelKod + ". Tjänstens meddelande: " + res.Meddelande;
					else
						csr.ErrorMessage = "Ett fel inträffade. Tjänstens meddelande: " + res.Meddelande;
				}
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientKursTillfalle>> GetKursTillfallenByKursId(string kursId)
		{
			ClientServiceResult<IEnumerable<ClientKursTillfalle>> csr = new ClientServiceResult<IEnumerable<ClientKursTillfalle>>();

			using (KursService svc = new KursService())
			{
				if (kursId.IsGuid())
				{
					csr.Data = svc.GetKursTillfallenByKursId(new Guid(kursId)).Select(k => k.ToClientContract()).OrderBy(k => k.KursDatum).ThenBy(k => k.Lokal);
				}
				else
				{
					csr.Data = svc.GetKursTillfallenByKursId(null).Select(k => k.ToClientContract()).OrderBy(k => k.KursDatum).ThenBy(k => k.Lokal);
				}
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<ClientKursTillfalle> GetKursTillfalle(string id)
		{
			ClientServiceResult<ClientKursTillfalle> csr = new ClientServiceResult<ClientKursTillfalle>();

			using (KursService svc = new KursService())
			{
				if (id.IsGuid())
				{
					csr.Data = svc.GetKursTillfalle(new Guid(id)).ToClientContract();
				}
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateKursTillfalle(KursTillfalleForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					KursTillfalle kt = svc.GetKursTillfalle(new Guid(form.Id));
					kt.Andrad = DateTime.Now;
					kt.AndradAv = SPContext.Current.Web.CurrentUser.Name;

					kt.UpdateContract(form);
					svc.UpdateKursTillfalle(kt);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateKursTillfalle(KursTillfalleForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					KursTillfalle kt = new KursTillfalle()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id,
						Id = Guid.NewGuid()
					};
					kt.UpdateContract(form);
					svc.CreateKursTillfalle(kt);

					try
					{
						svc.AddPersonKursTillfalle(kt.Id, Int32.Parse(form.Antal), SPContext.Current.Web.CurrentUser.Name);
					}
					catch (FormatException fe)
					{
						Logger.LogError(this, LayerNames.ClientService, "CreateKursTillfalle", "Formateringsfel", fe);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogError(this, LayerNames.ClientService, "CreateKursTillfalle", "Ett fel inträffade", ex);
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteKursTillfalle(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						svc.DeleteKursTillfalle(new Guid(id));
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.HasError = true;
				csr.ErrorMessage = "Kurstillfället gick inte att ta bort. Kontrollera att någon person inte är placerad på det";
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientKursTillfalle>> GetKursTillfalleByPersonId(string id)
		{
			ClientServiceResult<IEnumerable<ClientKursTillfalle>> csr = new ClientServiceResult<IEnumerable<ClientKursTillfalle>>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						var v = svc.GetKursTillfalleByPersonId(new Guid(id));
						if (v != null)
							csr.Data = v.Select(kt => kt.ToClientContract());
					}
				}
			}
			catch (Exception ex)
			{
				csr.HasError = true;
				csr.ErrorMessage = ex.Message;
			}

			return csr;
		}
		#endregion

		#region PersonKursTillfälle
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> TogglePersonKurstillfalleStatus(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						var v = svc.GetPersonKursTillfalle(new Guid(id));

						v.Status = v.Status == PersonKursTillfalle.StatusTyp.Placerad ? PersonKursTillfalle.StatusTyp.Narvaro : PersonKursTillfalle.StatusTyp.Placerad;

						svc.UpdatePersonKursTillfalle(v);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
		
		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> AddPersonKursTillfalle(PersonKursTillfalleForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (form.Id.IsGuid())
					{
						svc.AddPersonKursTillfalle(new Guid(form.Id), form.Antal, SPContext.Current.Web.CurrentUser.Name);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientPersonKursTillfalle>> GetPersonKursTillfallenByKursTillfalleId(string id)
		{
			ClientServiceResult<IEnumerable<ClientPersonKursTillfalle>> csr = new ClientServiceResult<IEnumerable<ClientPersonKursTillfalle>>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						csr.Data = svc.GetPersonKursTillfallenByKursTillfalleId(new Guid(id)).OrderBy(pkt => pkt.PersonUppdrag.Length == 0).ThenBy(pkt => pkt.PersonUppdrag).ThenByDescending(pkt => pkt.PersonId.HasValue).ThenBy(pkt => pkt.PersonNamn).Select(pkt => pkt.ToClientContract());
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeletePersonKursTillfalle(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						svc.DeletePersonKursTillfalle(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> PlaceraPersonTillKurs(KursPlatsForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (form.PersonId.IsGuid() && form.PersonKursTillfalleId.IsGuid())
					{
						PersonKursTillfalle pkt = svc.GetPersonKursTillfalle(new Guid(form.PersonKursTillfalleId));

						if (pkt != null)
						{
							pkt.PersonId = new Guid(form.PersonId);
							pkt.Andrad = DateTime.Now;
							pkt.AndradAv = SPContext.Current.Web.CurrentUser.Name;

							svc.UpdatePersonKursTillfalle(pkt);
						}
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> PlaceraValdistriktTillKurs(KursPlatsValdistriktForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					var v = form.ValdistriktId.Split(new String[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

					foreach (string id in v)
					{
						if (form.KursTillfalleId.IsGuid() && id.IsGuid())
						{
							svc.PlaceraValdistriktTillKursTillfalle(new Guid(id), new Guid(form.KursTillfalleId));
						}
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Det gick inte att placera valdistriktet på kurstillfället. Kontrollera att det finns tillräckligt många lediga platser.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> PlaceraGruppTillKurs(KursPlatsGruppForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (form.KursTillfalleId.IsGuid() && form.GruppId.IsGuid())
					{
						svc.PlaceraGruppTillKursTillfalle(new Guid(form.GruppId), new Guid(form.KursTillfalleId));
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Det gick inte att placera gruppet på kurstillfället. Kontrollera att det finns tillräckligt många lediga platser.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> RemovePersonFromPersonKursTillfalle(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (KursService svc = new KursService())
				{
					if (id.IsGuid())
					{
						PersonKursTillfalle pkt = svc.GetPersonKursTillfalle(new Guid(id));

						if (pkt != null)
						{
							pkt.PersonId = null;
							pkt.Andrad = DateTime.Now;
							pkt.AndradAv = SPContext.Current.Web.CurrentUser.Name;

							svc.UpdatePersonKursTillfalle(pkt);
						}
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
		#endregion
	}
}
